const path = require('path');
const fs = require("fs");
const cProcess = require("child_process");
const getCodes = require("../../tools/getCodes.js");
const cwd = process.cwd();
const Tools = require("./tools.js");
module.exports = function (data, socket, option) {
  const successMessages = [];
  const tools = Tools(option.ctoolsOpt.devToolsDir);
  const entryJson = tools.getEntryJson();
  const {name, dto, copyFile, updateAlias, userName} = data;
  entryJson.entry = name;
  tools.writeEntryJson(entryJson);
  const dtoToSave = JSON.parse(JSON.stringify(dto));

  dtoToSave.repertoryList.forEach(repertory => {
    delete repertory.branch;
    delete repertory.branches;
  });
  tools.writeWorkspaceConf(name, dtoToSave);
  try {
    getCodes(dto, option, name, successMessages);
    socket.emit("applySettingData", `checkoutBranch...`);
    checkoutBranch(dto, option, tools, socket, successMessages);

    socket.emit("applySettingSuccess", {workspace: tools.getWorkSpaces(entryJson.entry, userName), msgs: successMessages});
  } catch (e) {
    console.log(e);
    process.chdir(cwd);
    socket.emit("applySettingFail", {data: "fail", code: 1});
  }
};

function checkoutBranch(dto, option, tools, socket, successMessages) {
  dto.repertoryList.filter(item => !item.disabled).forEach(repertory => {
    const ori = repertory.branch.ori.branch;
    const tar = repertory.branch.tar.branch;
    const repertoryPath = path.join(cwd, dto.repertoryPath, repertory.name);
    process.chdir(repertoryPath);
    // 先检测是否有未提交的
    const status = cProcess.execSync(`git status`, {encoding: "utf-8"});
    if (!/nothing to commit, working tree clean/.test(status)) {
      successMessages.push({
        type: "err",
        msg: `当前仓库有未提交或未暂存的文件 ${repertory.name} ...`
      });
      socket.emit("applySettingData", `当前仓库有未提交或未暂存的文件 ${repertory.name} ...`);
      return;
    }
    const fetch = cProcess.execSync(`git fetch`, {encoding: "utf-8"});
    // 再检测远程分支是否有更新
    if (fetch) {
      // 远程分支有更新
      successMessages.push({
        type: "err",
        msg: `远程分支有更新 ${repertory.name} ...`
      });
      socket.emit("applySettingData", `远程分支有更新 ${repertory.name} ...`);
      return;
    }
    const allBranches = cProcess.execSync("git branch -a", {encoding: "utf-8"});
    const parsedBranch = tools.parseBranch(allBranches);
    // 检出分事不是当前分支时，才需要检出分支
    if (parsedBranch.current !== tar) {
      // 检出 要检出的源分支 // 如果源分支不存在 或者 已有分支不包含源分支， 并且要检出的分支也不再， 那么就返回
      // 如果
      if (
        // 没有源分支的话， 只能处理已有分支的情况 // 即 新分支，必须要设置源分支
        !ori && !parsedBranch.remote.includes(tar) && !parsedBranch.local.includes(tar) ||
        // 有源分支， 要保证源分支存在
        !(parsedBranch.remote.includes(ori) || parsedBranch.local.includes(ori))
      ) return;
      cProcess.execSync(`git checkout ${ori}`, {encoding: "utf-8"});
      // 拉取最新的源分支
      try {cProcess.execSync(`git pull`, {encoding: "utf-8"});} catch (e) {
        successMessages.push({
          type: "err",
          msg: `远程源分支不存在 ${repertory.name} ...`
        });
        socket.emit("applySettingData", `远程源分支不存在 ${repertory.name}  ${ori} ...`);
      }
      // 是否已有分支 // 如果没有就新建一个分支
      if (!parsedBranch.remote.includes(tar) && !parsedBranch.local.includes(tar)) {
        cProcess.execSync(`git branch ${tar}`);
      }
      // 然后检出分支 // 新建的也检出一下；
      cProcess.execSync(`git checkout ${tar}`, {encoding: "utf-8"});

      // 关联远程分支
      if (!parsedBranch.remote.includes(tar)) {
        cProcess.execSync(`git push origin ${tar}`, {encoding: "utf-8"});
      }
    } else {}
    // 拉取(切换后)分支的最新的代码
    try {
      cProcess.execSync(`git pull`, {encoding: "utf-8"});
    }catch(e) {
      successMessages.push({
        type: "err",
        msg: `远程目标分支分支不存在 ${repertory.name}  ${tar} ...`
      });
      socket.emit("applySettingData", `远程目标分支分支不存在 ${repertory.name}  ${tar} ...`);
    }
    socket.emit("applySettingData", `checkoutBranch ${repertory.name} ...`);
  });
  process.chdir(cwd);
}
